﻿using SMSGateWayAddIns;
using SMSGateWayCore.Message;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Data.SqlClient;
using System.Data.EntityClient;

namespace GateWayDataBase
{
    public class GateWayDataBase : ControllerAddInBase
    {
        Thread SendThread = null;

        [ImportProperty("连接字符串")]
        public string ConnectStr { get; set; }

        [ImportProperty("数据库类型")]
        public DBType ConnDBType { get; set; }

        [ImportProperty("查询数据间隔(秒)")]
        public int WaitTime { get; set; }

        [ImportProperty("每次查询数量")]
        public int SearchTopCount { get; set; }

        public override string TypeName
        {
            get { return "通用数据库"; }
        }

        public override string[] ProtocolRequired
        {
            get { return null; }
        }

        public GateWayDataBase()
        {
            SearchTopCount = 100;
            WaitTime = 2;
            ConnDBType = global::GateWayDataBase.DBType.MSSQL2005;
            ConnectStr = "Data Source=127.0.0.1;Initial Catalog=CMPP;UID=sa;Password=xxx";
        }

        EntityConnectionStringBuilder ecb;
        public override void OnLoad()
        {

            ecb = new EntityConnectionStringBuilder();

            ecb.ProviderConnectionString = ConnectStr;

            switch (ConnDBType)
            {
                case DBType.MSSQL2008:
                    ecb.Metadata = "res://*/SQL2008DB.csdl|res://*/SQL2008DB.ssdl|res://*/SQL2008DB.msl";
                    ecb.Provider = "System.Data.SqlClient";
                    break;
                case DBType.MSSQL2005:
                    ecb.Metadata = "res://*/SQL2005DB.csdl|res://*/SQL2005DB.ssdl|res://*/SQL2005DB.msl";
                    ecb.Provider = "System.Data.SqlClient";
                    break;
                case DBType.MYSQL:
                    ecb.Metadata = "res://*/MYSQLDB.csdl|res://*/MYSQLDB.ssdl|res://*/MYSQLDB.msl";
                    ecb.Provider = "MySql.Data.MySqlClient";
                    break;
            }


            SendThread = new Thread(SendThreadRun);
            SendThread.IsBackground = true;
            SendThread.Start();

        }

        public override void OnUnLoad()
        {
            if (SendThread != null)
            {
                SendThread.Abort();
                SendThread = null;
            }
        }

        void SendThreadRun()
        {
            while (true)
            {
                if (IsConnected)
                {
                    try
                    {
                        using (var _Entities = new DBEntities(ecb.ConnectionString))
                        {
                            var sendingsms = _Entities.SendingSMS.Where(p => p.SendStatus == -1).OrderBy(p => p.BatchNo).OrderBy(p => p.Priority).Take(SearchTopCount).ToList();
                            //0 complete
                            //-1 nosend
                            //-2 waitsend
                            //-3 sending
                            //-4 timeout
                            foreach (var sms in sendingsms)
                            {
                                if (sms.SendTime.HasValue && sms.SendTime.Value >= DateTime.Now)
                                {
                                    continue;
                                }

                                SMSSubmitMessage message = new SMSSubmitMessage();
                                //消息接收号码
                                message.DestTerminalID = sms.DestTerminalID;
                                //资费代码
                                message.FeeCode = 0;
                                //被计费用户的号码
                                message.FeeTerminalID = sms.DestTerminalID;
                                //资费类别
                                message.FeeType = FeeTypes.Free;
                                //计费用户类型字段
                                message.FeeUserType = FeeUserTypes.Termini;
                                //点播业务使用的LinkID
                                message.LinkID = sms.LinkID;
                                //消息内容
                                message.MsgContent = sms.MsgContent;
                                //是否要求返回状态确认报告
                                message.NeedReport = true;
                                //业务标识
                                message.ServiceID = sms.ServiceID;
                                //消息发送号码
                                message.SrcTerminalID = sms.SrcTerminalID;
                                if (sms.ExpandNo != null)
                                {
                                    message.SrcTerminalID += sms.ExpandNo;
                                }
                                SubmitMessage(message, null, sms);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        SendMessage(new ErrorMessage(ex));
                    }
                }
                Thread.Sleep(WaitTime * 1000);
            }
        }

        protected override bool DeliverMessage(SMSDeliverMessage pMessage)
        {
            using (var _Entities = new DBEntities(ecb.ConnectionString))
            {
                _Entities.DeliverSMS.Add(new DeliverSMS()
                {
                    DeliverTime = DateTime.Now,
                    DestTerminalID = pMessage.DestTerminalID,
                    LinkID = pMessage.LinkID,
                    MsgContent = pMessage.MsgContent,
                    ServiceID = pMessage.ServiceID,
                    SrcTerminalID = pMessage.SrcTerminalID
                });
                _Entities.SaveChanges();
                pMessage.AssignProcessResult(true);
                return false;
            }
        }

        protected override bool ReprotMessage(SMSReportMessage pMessage)
        {
            using (var _Entities = new DBEntities(ecb.ConnectionString))
            {
                string reportmsgid = pMessage.MsgID.ToString();
                SendingSMS sendingsms = _Entities.SendingSMS.Where(p => p.MsgID == reportmsgid).FirstOrDefault();

                if (sendingsms != null)
                {
                    SubmitSMS submitsms = CopySubmitSMS(sendingsms);
                    submitsms.ReportStatus = pMessage.Status;
                    submitsms.ReportTime = DateTime.Now;
                    _Entities.SubmitSMS.Add(submitsms);
                    _Entities.SaveChanges();
                    _Entities.Database.ExecuteSqlCommand("DELETE SendingSMS WHERE ID = {0}", sendingsms.ID);
                    pMessage.AssignProcessResult(true);
                    return false;
                }
            }

            return true;
        }

        protected override bool SubmitMessageStatus(SubmitStatusMessage pMessage)
        {
            if (pMessage.aSyncState is SendingSMS)
            {
                using (var _Entities = new DBEntities(ecb.ConnectionString))
                {
                    var sendingsms = pMessage.aSyncState as SendingSMS;

                    if (pMessage.Status == SMSGateWayCore.SubmitMessageStatus.WaitSend)
                    {
                        if (sendingsms.SendStatus == -1)
                        {
                            sendingsms.SendStatus = -2;
                            _Entities.Database.ExecuteSqlCommand("UPDATE SendingSMS SET SendStatus = {0} WHERE ID = {1}", -2, sendingsms.ID);
                        }
                    }

                    //if (pMessage.Status == SMSGateWayCore.SubmitMessageStatus.Sending)
                    //{
                    //    if (sendingsms.SendStatus == -2)
                    //    {
                    //        sendingsms.SendStatus = -3;
                    //        sendingsms.SendTime = DateTime.Now;
                    //        _Entities.Database.ExecuteSqlCommand("UPDATE SendingSMS SET SendStatus = {0}, SendTime = {1} WHERE ID = {2}", -3, DateTime.Now.ToString(), sendingsms.ID);
                    //    }
                    //}

                    if (pMessage.Status == SMSGateWayCore.SubmitMessageStatus.Timeout)
                    {
                        sendingsms.SendStatus = -1;
                        sendingsms.SendTime = null;
                        _Entities.Database.ExecuteSqlCommand("UPDATE SendingSMS SET SendStatus = {0}, SendTime = NULL WHERE ID = {1}", sendingsms.SendStatus, sendingsms.ID);
                    }

                    if (pMessage.Status == SMSGateWayCore.SubmitMessageStatus.Complete)
                    {
                        sendingsms.MsgID = pMessage.RespMessage.MsgID.ToString();
                        sendingsms.SendStatus = (int)pMessage.RespMessage.Status;
                        sendingsms.SendTime = DateTime.Now;

                        if (sendingsms.SendStatus == 0)
                        {
                            _Entities.Database.ExecuteSqlCommand("UPDATE SendingSMS SET SendStatus = {0}, SendTime = {1},MsgID = {2} WHERE ID = {3}", sendingsms.SendStatus, DateTime.Now.ToString(), sendingsms.MsgID, sendingsms.ID);
                        }
                        else
                        {
                            SubmitSMS submitsms = CopySubmitSMS(sendingsms);
                            _Entities.SubmitSMS.Add(submitsms);
                            _Entities.SaveChanges();
                            _Entities.Database.ExecuteSqlCommand("DELETE SendingSMS WHERE ID = {0}", sendingsms.ID);
                        }
                    }
                }
            }
            return false;
        }

        protected SubmitSMS CopySubmitSMS(SendingSMS sendingsms)
        {
            return new SubmitSMS()
                        {
                            DestTerminalID = sendingsms.DestTerminalID,
                            LinkID = sendingsms.LinkID,
                            MsgContent = sendingsms.MsgContent,
                            SendStatus = sendingsms.SendStatus,
                            SendTime = sendingsms.SendTime,
                            ServiceID = sendingsms.ServiceID,
                            SrcTerminalID = sendingsms.SrcTerminalID,
                            MsgID = sendingsms.MsgID
                        };
        }
    }
}